from django.core.cache import cache
from django.conf import settings
import random
import logging
from datetime import datetime

logger = logging.getLogger(__name__)

# 默认配置
DEFAULT_VERIFICATION_CONFIG = {
    'LENGTH': 6,
    'EXPIRE_MINUTES': 5,
    'INTERVAL_SECONDS': 60,
    'MAX_DAILY_SENDS': 10,
    'TEST_MODE': True,
    'TEST_CODE': '123456'
}


class VerificationService:
    """验证码服务"""

    @staticmethod
    def _get_cache_key(phone: str, prefix: str = 'code') -> str:
        """获取缓存键"""
        return f"sms:{prefix}:{phone}"

    @classmethod
    def get_config(cls):
        """获取验证码配置"""
        try:
            from django.conf import settings
            if hasattr(settings, 'VERIFICATION_CODE'):
                return settings.VERIFICATION_CODE
            return DEFAULT_VERIFICATION_CONFIG
        except Exception as e:
            logger.warning(f"无法获取验证码配置，使用默认配置: {str(e)}")
            return DEFAULT_VERIFICATION_CONFIG

    @staticmethod
    def generate_code(length: int = None) -> str:
        """生成验证码"""
        config = VerificationService.get_config()
        if config.get('TEST_MODE', False):
            return config.get('TEST_CODE', '123456')
        length = length or config.get('LENGTH', 6)
        return ''.join(random.choices('0123456789', k=length))

    @classmethod
    def save_code(cls, phone: str, code: str) -> bool:
        """保存验证码"""
        try:
            cache_key = cls._get_cache_key(phone)
            config = cls.get_config()
            timeout = config.get('EXPIRE_MINUTES', 5) * 60
            cache.set(cache_key, code, timeout=timeout)
            return True
        except Exception as e:
            logger.error(f"保存验证码失败: {str(e)}")
            return False

    @classmethod
    def verify_code(cls, phone: str, code: str) -> bool:
        """验证验证码"""
        try:
            cache_key = cls._get_cache_key(phone)
            saved_code = cache.get(cache_key)

            if not saved_code:
                return False

            # 验证成功后删除验证码
            if saved_code == code:
                cache.delete(cache_key)
                return True

            return False

        except Exception as e:
            logger.error(f"验证码验证失败: {str(e)}")
            return False

    @classmethod
    def can_send_sms(cls, phone: str) -> bool:
        """检查是否可以发送短信"""
        try:
            config = cls.get_config()

            # 检查发送间隔
            interval_key = cls._get_cache_key(phone, 'interval')
            if cache.get(interval_key):
                return False

            # 检查每日发送次数
            count_key = cls._get_cache_key(phone, 'count')
            daily_count = cache.get(count_key) or 0

            if daily_count >= config.get('MAX_DAILY_SENDS', 10):
                return False

            # 设置发送间隔
            interval_seconds = config.get('INTERVAL_SECONDS', 60)
            cache.set(interval_key, 1, timeout=interval_seconds)

            # 更新每日发送次数
            today_end = datetime.now().replace(hour=23, minute=59, second=59)
            seconds_until_end = (today_end - datetime.now()).seconds
            cache.set(count_key, daily_count + 1, timeout=seconds_until_end)

            return True
        except Exception as e:
            logger.error(f"检查发送限制失败: {str(e)}")
            return True  # 如果检查失败，允许发送